package seatiger.tomcat.catalina.startup;

import org.apache.commons.digester.Digester;
import seatiger.tomcat.catalina.Connector;
import seatiger.tomcat.catalina.Server;
import seatiger.tomcat.catalina.Service;
import seatiger.tomcat.catalina.connector.AbstractConnector;
import seatiger.tomcat.catalina.connector.CoyoteConnector;
import seatiger.tomcat.catalina.core.StandardServer;
import seatiger.tomcat.catalina.core.StandardService;

import java.io.File;
import java.io.FileInputStream;

/**
 * 负责容器的解析 和启动
 */
public class Catalina {

    protected Server server;
    protected String configFile = "conf/server.xml";

    public void setServer(Server server) {
        this.server = server;
    }

    public Catalina process(){
        setCatalinaBase();
        start();
        return this;
    }

    private void start() {
        Digester digester = createStartDigester();
        try(FileInputStream stream = new FileInputStream(configFile())) {
            digester.push(this);
            digester.parse(stream);
        }catch (Exception e){
            System.out.println("Catalina.start: " + e);
            e.printStackTrace(System.out);
            System.exit(1);
        }
    }

    private Digester createStartDigester() {
        Digester digester = new Digester();
        serverRS(digester);
        serverServiceRS(digester);
        serverServiceConnectorRS(digester);
        digester.addRuleSet(new EngineRuleSet("Server/Service/"));
        digester.addRuleSet(new HostRuleSet("Server/Service/Engine/"));
        digester.addRuleSet(new ContextRuleSet("Server/Service/Engine/Host/"));
        return digester;
    }

    /**
     * 解析server 元素的规则
     * @param digester
     */
    private void serverRS(Digester digester) {
        //创建对象
        digester.addObjectCreate("Server", StandardServer.class);
        digester.addSetProperties("Server");
        digester.addSetNext("Server","setServer",Server.class.getName());
    }

    private void serverServiceRS(Digester digester){
        digester.addObjectCreate("Server/Service", StandardService.class);
        digester.addSetProperties("Server/Service");
        digester.addSetNext("Server/Service","addService", Service.class.getName());
    }

    private void serverServiceConnectorRS(Digester digester){
        digester.addRule("Server/Service/Connector",new CoyoteConnectorCreateRule());
//        digester.addObjectCreate("Server/Service/Connector", CoyoteConnector.class);
        digester.addSetProperties("Server/Service/Connector");
        digester.addSetNext("Server/Service/Connector","addConnector", Connector.class.getName());
    }

    /**
     * 获取默认的 conf/server.xml
     * @return
     */
    protected File configFile() {
        File file = new File(configFile);
        if (!file.isAbsolute())
            file = new File(System.getProperty("catalina.base"), configFile);
        return file;
    }

    protected void setCatalinaBase() {
        if (System.getProperty("catalina.base") != null){
            return;
        }
        System.setProperty("catalina.base", System.getProperty("catalina.home"));
    }
}
